﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Diagnostics;
using System.Runtime.InteropServices;//网络连接命名空间
using System.Configuration;
using System.Xml;

namespace adlaunch
{

    public partial class Form1 : Form
    {
        [DllImport("user32.dll", EntryPoint = "SetWindowPos", SetLastError = true)]
        static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, uint uFlags);

        [DllImport("User32.dll", EntryPoint = "SetForegroundWindow")]
        static extern bool SetForegroundWindow(IntPtr hWnd);

        [DllImport("user32.dll", SetLastError = true)]
        static extern bool PostMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);

        [DllImport("user32.dll", EntryPoint = "FindWindow")]
        static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        [DllImport("user32.dll")]
        static extern IntPtr FindWindowEx(IntPtr hwndParent, int hwndChildAfter, string lpszClass, string lpszWindow);

        [DllImport("User32.dll")]
        static extern int GetWindowText(IntPtr handle, StringBuilder text, int MaxLen);

        // PostMessage
        uint WM_LBUTTONDOWN = 0x201;
        uint WM_LBUTTONUP = 0x202;
        uint WM_RBUTTONDOWN = 0x0204;
        uint WM_RBUTTONUP = 0x0205;
        uint WM_MOUSEMOVE = 0x0200;

        uint WM_KEYDOWN = 0x0100;
        uint WM_KEYUP = 0x0101;

        int KEY_ENTER = 0x0D;
        int KEY_F11 = 0x7A;

        String[] urls = new String[2];

        //public string exe = @"C:\Users\rome\AppData\Local\Google\Chrome\Application\chrome.exe";
        public string exe = @"C:\youdao\";
        Boolean AUTO = false;
        public Form1()
        {
            InitializeComponent();

            string chrome = ConfigurationSettings.AppSettings["chrome"];
            string url1 = ConfigurationSettings.AppSettings["url1"];
            string url2 = ConfigurationSettings.AppSettings["url2"];

            if (chrome != null && !chrome.Equals(""))
            {
                this.exe = chrome;

            }

            if (url1 != null && !url1.Equals(""))
            {
                this.textBox1.Text = url1;
            }

            if (url2 != null && !url2.Equals(""))
            {
                this.textBox2.Text = url2;
            }
            this.textBox3.Text = this.exe;
        }
        public Form1(bool auto)
            : this()
        {
            AUTO = auto;
        }


        private void button1_Click(object sender, EventArgs e)
        {
            closeAll();
            Thread.Sleep(3000);
            init();
            display();

        }
        private void init()
        {
            urls[0] = this.textBox1.Text;
            urls[1] = this.textBox2.Text;
        }

        private IntPtr find(string name)
        {

            System.Diagnostics.Process[] allProcesses = System.Diagnostics.Process.GetProcesses();
            for (int i = 0; i < allProcesses.Length; i++)
            {

                if (allProcesses[i].ProcessName == "node")
                {
                    //log(allProcesses[i].ProcessName);

                    if (allProcesses[i].MainWindowHandle != IntPtr.Zero)
                    {
                        StringBuilder text = new StringBuilder(512);
                        GetWindowText(allProcesses[i].MainWindowHandle, text, 512);
                        if (name.Equals(text.ToString()))
                        {
                            log(allProcesses[i].MainWindowHandle.ToString() + "||" + text);
                            return allProcesses[i].MainWindowHandle;
                        }
                    }
                }
            }
            return IntPtr.Zero;
        }

        private void display()
        {
            int count = 1;
            this.loginfo.Text += "正在检查网络连接....\r\n";
            this.loginfo.Refresh();
            //MessageBox.Show(this.checkInternet()+"");
            if (this.checkInternet().Equals("success"))
            {
                showLog("网络连接正常,开始初始化系统应用....");
                this.loginfo.Refresh();
                InitApp();
            }
            else
            {
                showLog("网络连接失败,开始修复网卡设备....");
                do
                {
                    if (count > 5) //最多修复5次
                    {
                        break;
                    }
                    //重新识别usb,一直到网络连接正常
                    showLog("正在尝试第" + count + "次修复....") ;
                    this.reloadUsb();
                    count++;
                    Thread.Sleep(Convert.ToInt32(this.getXmlValue("threadTime"))); //线程停滞时间从app.xml中读取,之后判断网络状态
                } while (this.checkInternet().Equals("fail"));
                //修复完成之后.联网正常,两秒后打开程序
                
                if (this.checkInternet().Equals("success"))
                {
                    showLog("修复完成,正在打开应用.......");
                    Thread.Sleep(2000);
                    InitApp();
                }
                else
                {
                    //重启电脑
                    showLog("修复失败,设备将5秒后自动重启.......");
                    this.restartComputer();
                }
            }
            

        }

        private void showLog(String logText)
        {
            this.loginfo.Text += logText+"\r\n";
            this.loginfo.Refresh();
        }
        //运行app
        private void InitApp()
        {
            Screen[] s = Screen.AllScreens;
            showLog("共" + s.Length + "块屏幕");
            Rectangle[] ScreensRect = new Rectangle[s.Length];
            for (int i = 0; i < s.Length; i++)
            {

                showLog("第" + s[i].DeviceName + "块屏幕");
                ScreensRect[i] = s[i].WorkingArea;

                showLog("Height :" + ScreensRect[i].Height);
                showLog("Width :" + ScreensRect[i].Width);

                showLog("X :" + ScreensRect[i].X);

                showLog("Y :" + ScreensRect[i].Y);
                Application.DoEvents();
                this.start(ScreensRect[i].X, ScreensRect[i].Width, ScreensRect[i].Height, urls[i]);

            }
        }
        //声明外部的函数：
        //private static extern bool InternetGetConnectedState(
        //    ref  int dwFlag,
        //    int dwReserved
        //);

        /**
         * 
         *检查外网连接是否正常, 
         */

        private String checkInternet()
        {
            Process proIP = commandProject();
            proIP.Start(); 
            proIP.StandardInput.WriteLine("ping  www.baidu.com"); 
            proIP.StandardInput.WriteLine("exit"); 
            string  strResult=proIP.StandardOutput.ReadToEnd();
            String result = (strResult.IndexOf("(0% loss)") != -1) ? "success" : "fail";
            proIP.Close();
            return result;           
        }

        private void start(int x, int w, int h, String url)
        {

            Process p = commandProject();
            Application.DoEvents();
            p.StartInfo.FileName = exe + url + @"\app.exe";//需要启动的程序名
            p.Start();//启动       
            Application.DoEvents();
            Thread.Sleep(10000);
            Application.DoEvents();
            IntPtr hMainWindow = find(url);
            SetWindowPos(hMainWindow, (IntPtr)(0), x, 0, w, h, 0x0040);
            Thread.Sleep(1000);
            SetForegroundWindow(hMainWindow);

        }

        private void log(string str)
        {
            this.loginfo.Text += str + "\r\n";
        }

        private void button2_Click(object sender, EventArgs e)
        {
            find("weibo");
        }
        // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
        /// <summary>
        /// 关闭IE窗口
        /// </summary>
        private void closeAll()
        {
            Process[] process = Process.GetProcesses();
            for (int i = 0; i < process.Length; i++)
            {
                if (process[i].ProcessName.ToLower() == "node")
                {
                    try
                    {
                        process[i].Kill();
                        process[i].Close();
                        Application.DoEvents();
                        Thread.Sleep(300);
                    }
                    catch
                    {
                    }
                }
            }
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (AUTO)
            {
                this.button1_Click(sender, e);
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
           // MessageBox.Show(getXmlValue("threadTime")+"");
            int screenWidth = Screen.PrimaryScreen.Bounds.Width,
                screenHeight = Screen.PrimaryScreen.Bounds.Height,
                formWidth = this.Width,formHeight=this.Height;

            //设置显示位置
            this.Location = new Point(screenWidth-formWidth,0);
            System.Timers.Timer timer1 = new System.Timers.Timer();
            timer1.Elapsed += new System.Timers.ElapsedEventHandler(timer1_Tick);
            timer1.Interval = 5000;
            timer1.AutoReset = false;
            timer1.Enabled = true;
            timer1.Start();
        }
        /**
         * 可以将 DevCon 用于 Microsoft Windows 2000、Windows XP 和 Windows Server 2003，但不能将其用于 Windows 95、Windows 98 或 Windows Millennium Edition
            其次，你需要记住如下命令：
            （1）、devcon disable USB\Class_08，使所有的USB移动存储设备失去作用。（禁用）
            （2）、devcon enable USB\Class_08，使连接在电脑上的USB移动存储设备起效。（启用）
            以上命令，实际上只是禁用USB，而USB还是连接在电脑上的。你可以观察到右下角的状态栏上还有移动设备的图标。
            （3）、devcon remove USB\Class_08，移除连接在电脑上的USB移动存储设备。进行该操作之后，就可以将USB设备拔掉了。
            （4）、如果你使用了第三个命令之后没有拔掉USB设备，你想让他重新识别，也可以。记住以下的命令：
                   devcon rescan，这个时候电脑会重新扫描硬件改动，从而让USB重新被识别。
            备注：经过实际的操作，可以这么区分disable和remove——disable跟我们操作中的禁用设备一样，实际上设备还连在电脑上，只要启用就可以直接用该设备；而remove则是断电，跟“安全删除硬件”操作一样，进行该操作之后，就可以拔除设备了。
         * 重新识别usb驱动(重新初始化网卡)
         * */
        private void reloadUsb()
        {
           
            Process p = commandProject();
            p.Start();
            //修复USB的方式,根据app.xml配置来选择修复方式;
            //0为重新识别;1为禁用再启用
            if (this.getXmlValue("usbRestart") == 0)
            {
                //1,rescan重新识别;
                usb_Rescan(p);
            }
            else
            {
                //2,禁用再启用
                usb_Disable_Enable(p);
            }
            p.StandardInput.WriteLine("exit");
            p.Close();


        }
        //重新识别
        private static void usb_Rescan(Process p)
        {
            p.StandardInput.WriteLine("devcon rescan");
        }
        //禁用,再启用
        private static void usb_Disable_Enable(Process p)
        {
            p.StandardInput.WriteLine("devcon disable USB\\Class_08");
            p.StandardInput.WriteLine("devcon enable USB\\Class_08");
        }
        //返回一个cmd.exe对象
        private static Process commandProject()
        {
            Process p = new Process();
            p.StartInfo.FileName = "cmd.exe";
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.RedirectStandardInput = true;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.RedirectStandardError = true;
            p.StartInfo.CreateNoWindow = false;//true表示不显示黑框，false表示显示dos界面
            return p;
        }
        //5秒后重启电脑
        private void restartComputer() {
            showLog("设备重启中.....");
            Process p = commandProject();
            try
            {
                p.Start();
                p.StandardInput.WriteLine("shutdown -r -t 5");
                p.StandardInput.WriteLine("exit");

            }
            catch { }
            finally {
                p.Close();
            }
            
        }
        //读取xml
        private int getXmlValue(String keyStr)
        {
            int result = 0;
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(exe+"\\app.xml");

            XmlNodeList nodeList = xmlDoc.SelectSingleNode("pros").ChildNodes;//获取bookstore节点的所有子节点
            foreach (XmlNode xn in nodeList)//遍历所有子节点
            {
                XmlElement xe = (XmlElement)xn;//将子节点类型转换为XmlElement类型
                String nameValue = xe.GetAttribute("name");
                if (keyStr.Equals(nameValue)) {
                    result= Convert.ToInt32(xe.InnerText.ToString());
                }                
            }
            return result;
        }




    }
}
